package com.lcf.app.ws;

import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;
import ws.schild.jave.info.MultimediaInfo;
import ws.schild.jave.process.ProcessWrapper;
import ws.schild.jave.process.ffmpeg.DefaultFFMPEGLocator;
import ws.schild.jave.progress.EncoderProgressListener;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 音视频工具类：
 * <br/>
 * 参考文档：
 */
public class FFmpegUtils {

    /**
     * 视频转为mp4
     *
     * @param input
     * @param output
     * @throws EncoderException
     * @throws MalformedURLException
     */
    public static void videoToMp4(String input,
                                  String output,
                                  EncoderProgressListener encoderProgressListener) throws EncoderException, MalformedURLException {
        VideoAttributes videoAttributes = new VideoAttributes();
        videoAttributes.setCodec("libx264");
        AudioAttributes audioAttributes = new AudioAttributes();
        audioAttributes.setCodec("aac");
        //
        EncodingAttributes encodingAttributes = new EncodingAttributes();
        encodingAttributes.setOutputFormat("mp4");
        encodingAttributes.setVideoAttributes(videoAttributes);
        encodingAttributes.setAudioAttributes(audioAttributes);
        // 编码
        encode(input, new File(output), encodingAttributes, encoderProgressListener);
    }

    /**
     * 音频转为mp3
     *
     * @param input
     * @param output
     * @throws EncoderException
     * @throws MalformedURLException
     */
    public static void audioToMp3(String input,
                                  String output,
                                  EncoderProgressListener encoderProgressListener) throws EncoderException, MalformedURLException {
        AudioAttributes audioAttributes = new AudioAttributes();
        audioAttributes.setCodec("libmp3lame");
        //
        EncodingAttributes encodingAttributes = new EncodingAttributes();
        encodingAttributes.setOutputFormat("mp3");
        encodingAttributes.setAudioAttributes(audioAttributes);
        // 编码
        encode(input, new File(output), encodingAttributes, encoderProgressListener);
    }

    /**
     * 剪切音视频:返回 star:[offset] -> end:[duration+offset]
     *
     * @param offset                  开始时间:秒
     * @param duration                持续时间:秒
     * @param input
     * @param output
     * @param encoderProgressListener
     * @throws EncoderException
     * @throws MalformedURLException
     */
    public static void cut(Float offset,
                           Float duration,
                           String input,
                           String output,
                           EncoderProgressListener encoderProgressListener) throws EncoderException, MalformedURLException {
        //
        EncodingAttributes encodingAttributes = new EncodingAttributes();
        encodingAttributes.setAudioAttributes(new AudioAttributes()
                .setCodec(AudioAttributes.DIRECT_STREAM_COPY)
        );
        encodingAttributes.setVideoAttributes(new VideoAttributes()
                .setCodec(VideoAttributes.DIRECT_STREAM_COPY)
        );
        encodingAttributes.setDuration(duration);
        encodingAttributes.setOffset(offset);
        // 编码
        encode(input, new File(output), encodingAttributes, encoderProgressListener);
    }

    /**
     * 执行编码命命令
     *
     * @param input
     * @param output
     * @param encodingAttributes
     * @throws EncoderException
     * @throws MalformedURLException
     */
    private static void encode(String input,
                               File output,
                               EncodingAttributes encodingAttributes,
                               EncoderProgressListener encoderProgressListener) throws EncoderException, MalformedURLException {
        Encoder encoder = new Encoder();
        MultimediaObject multimediaObject;
        if (input.startsWith("http")) {
            multimediaObject = new MultimediaObject(new URL(input));
        } else {
            multimediaObject = new MultimediaObject(new File(input));
        }
        encoder.encode(
                multimediaObject
                , output, encodingAttributes, encoderProgressListener);
    }

    /**
     * 使用命令的方式调用ffmpeg功能
     *
     * @param args
     */
    private static void command(String... args) {
        try (
                ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor()
        ) {
            System.err.println("================== <Start> ==================");
            for (String arg : args) {
                ffmpeg.addArgument(arg);
            }
            ffmpeg.execute();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
                String lineStr;
                while ((lineStr = br.readLine()) != null) {
                    System.out.println(lineStr);
                }
            }
            System.err.println("================== <End> ==================");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试执行命令
     *
     * @param args
     */
    public static void main(String[] args) throws EncoderException, MalformedURLException {
        /*

        String input = "C:\\Users\\Administrator\\Documents\\WeChat Files\\wxid_bij0qf56w0ib21\\FileStorage\\File\\2023-08\\0c10982d96771ec38f3e6b3cbf5fe89a_raw-0001.MPG";
        String output = "F:/ToMp4ToMp4.mp4";
        command("-i", input, "-c:v", "libx264", output, "-y");

        */

        /*String input = "F:\\迅雷下载\\阳光电影dy.ygdy8.com.疾速追杀4.2023.HD.1080P.中英双字.mkv";
        String output = "F:\\迅雷下载\\阳光电影dy.ygdy8.com.疾速追杀4.2023.HD.1080P.中英双字___.mkv";

        cut(55.0F, 80F, input, output, new EncoderProgressListener() {
            @Override
            public void sourceInfo(MultimediaInfo info) {

            }

            @Override
            public void progress(int permil) {
                System.out.println(permil);
            }

            @Override
            public void message(String message) {

            }
        });*/

        //command("-i", "D:\\CloudMusic\\Bill Conti - Gonna Fly Now.mp3", "-lavfi", "\"showwavespic=s=640x480\"", "-frames:v", "1", "D:\\CloudMusic\\廖健 - 斗地主.mp3.png", "-y");
        // ffmpeg - i input_audio.mp3 - lavfi "showwavespic=s=640x480" - frames:v 1 output_waveform.png

        MultimediaObject multimediaObject = new MultimediaObject(new File("C:\\Users\\ljd\\Desktop\\export\\LXS-LXS.mp4"));
        MultimediaInfo info = multimediaObject.getInfo();
        System.out.println(info);
        // ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=noprint_wrappers=1:nokey=1 input_video.mp4
        // ffprobe -select_streams v -show_entries format=duration,size,bit_rate,filename -show_streams -v quiet -of csv="p=0" -of json -i test.mp4
        String cmd = "ffprobe -select_streams v -show_entries format=duration,size,bit_rate,filename -show_streams -v quiet -of csv=\"p=0\" -of json -i %s";
        cmd = String.format(cmd, "C:\\Users\\ljd\\Desktop\\export\\LXS-LXS.mp4");
        String[] arr = cmd.split(" ");
        command(arr);

    }

}
